package com.mnsq.common.tools.jpa;

import com.mnsq.common.bean.annotation.JpaFields;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 对象转换，将c对象转到v对象
 *
 * @author Administrator
 * @date 2019/3/21 0021
 */
public class ReflectValueUtil<C, V> {
    private static Logger logger = LogManager.getLogger(ReflectValueUtil.class);

    private ReflectValueUtil() {
    }

    public static ReflectValueUtil getInstance() {
        return new ReflectValueUtil();
    }

    /**
     * 对象转换，将c对象属性值转到v对象属性值（通过注解指定属性字段）
     *
     * @param c
     * @param v
     */
    public void convertToObject(C c, V v) {
        Field[] declaredFields = c.getClass().getDeclaredFields();
        Field declaredField;
        for (Field fd : declaredFields) {
            try {
                fd.setAccessible(true);
                // 查询条件为空时，不做处理
                if (fd.get(c) == null) {
                    continue;
                }
                String name = fd.getName();
                Class<?> type = fd.getType();
                JpaFields annotation = fd.getAnnotation(JpaFields.class);
                if (annotation != null) {
                    if (annotation.ignore()) {
                        continue;
                    }
                    // 若注解内指定字段名称，则使用指定字段名称
                    if (annotation.fieldName() != null) {
                        name = annotation.fieldName();
                    }
                }
                declaredField = v.getClass().getDeclaredField(name);
                declaredField.setAccessible(true);
                declaredField.set(v, fd.get(c));
            } catch (IllegalAccessException e) {
                logger.error("ignore field :" + e.getMessage());
                continue;
            } catch (NoSuchFieldException e) {
                logger.error("ignore field :" + e.getMessage());
                continue;
            }
        }
    }

    /**
     * 将对象转换成map，忽略空值
     *
     * @param o
     * @param t
     * @param <T>
     * @return
     */
    public static <T> Map<String, String> objToMap(T o, Class<T> t) {
        if (t == null) {
            return Collections.emptyMap();
        }
        Map<String, String> map = new HashMap<>();
        for (Class<?> c = t; c != Object.class; c = t.getSuperclass()) {
            Object obj;
            for (Field fd : c.getDeclaredFields()) {
                fd.setAccessible(true);
                try {
                    if ((obj = fd.get(o)) == null) {
                        continue;
                    }
                    map.put(fd.getName(), obj.toString());
                } catch (Exception e) {
                }
            }
        }
        return map;
    }
}
